package logic;

import dto.MedicoDTO;
import dto.ObraSocialPlanDTO;
import dto.PacienteDTO;
import dto.TurnoDTO;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import jr.LiquidacionJR;

/**
 *
 * @author lucifer
 */
public class LiquidacionObraSocial {

  // La liquidacion de obras sociales se ordena por médico y luego por día.
  // Si el mes está incompleto, el reporte muesta las liquidaciones hasta el día
  // actual.

  private int idObraSocial;
  private LocalDate firstDayOfMonth;
  private ArrayList<TurnoDTO> turnosDelMes;

  private Map<Integer, Double> totalPorMedico;
  private double total;

  public LiquidacionObraSocial(int idObraSocial, LocalDate firstDayOfMonth) throws SQLException {
    LocalDate monthEnd = (this.firstDayOfMonth = firstDayOfMonth).plusMonths(1).plusDays(-1);
    turnosDelMes = Turno.SearchTurnosAsistidosByObraSocialFromDateToDate(this.idObraSocial = idObraSocial, firstDayOfMonth, monthEnd, true);
    totalPorMedico = new HashMap<>();

    int idMedico;
    for (TurnoDTO t : turnosDelMes) {
      if (totalPorMedico.containsKey(idMedico = t.getIdMedico())) {
        continue;
      }
      totalPorMedico.put(idMedico, 0.0);
    }

    setTotales();
  }

  private void setTotales() throws SQLException {
    for (TurnoDTO t : turnosDelMes) {
      int idMedico = t.getIdMedico();
      totalPorMedico.replace(idMedico, totalPorMedico.get(idMedico) + t.getMontoConsulta());
    }

    for (double monto : totalPorMedico.values()) {
      total += monto;
    }
  }

  public ArrayList<LiquidacionJR> GenerarLiquidacion() throws SQLException {
    ArrayList<LiquidacionJR> l = new ArrayList<>();

    String obraSocial = ObraSocial.SearchByID(idObraSocial).getNombre();

    if (turnosDelMes.isEmpty()) {
      l.add(new LiquidacionJR(
        String.format("%s de %d", firstDayOfMonth.getMonth().getDisplayName(TextStyle.FULL, Locale.forLanguageTag("es")), firstDayOfMonth.getYear()),
        "", "", "",
        "$ 0",
        String.format("%s de %d", firstDayOfMonth.getMonth().getDisplayName(TextStyle.FULL, Locale.forLanguageTag("es")), firstDayOfMonth.getYear()), "",
        "no hubo consultas", "-", obraSocial, "vacío", "-",
        null, null,
        "$ 0", "$ 0", null, "$ 0"));
      return l;
    }

    for (TurnoDTO t : turnosDelMes) {
      MedicoDTO m = Medico.SearchByID(t.getIdMedico());
      PacienteDTO p = Paciente.SearchByID(t.getIdPaciente());
      ObraSocialPlanDTO plan = ObraSocialPlan.SearchByID(t.getIdPlanConsulta());

      l.add(new LiquidacionJR(
        String.format("%s de %d", firstDayOfMonth.getMonth().getDisplayName(TextStyle.FULL, Locale.forLanguageTag("es")), firstDayOfMonth.getYear()),
        String.format("%s %s", m.getNombre(), m.getApellido()), Especialidad.SearchByID(m.getIdEspecialidad()).getNombre(), m.getMatricula(), String.format("$%9.2f", t.getMontoConsulta()),
        t.getFecha().toLocalDate().format(DateTimeFormatter.ofPattern("dd/MM")), t.getFecha().toLocalTime().toString(),
        String.format("%s %s", p.getNombre(), p.getApellido()), null,
        obraSocial, plan.getNombre(), String.format("%d", p.getNAfiliado()),
        null, null,
        String.format("$%9.2f", totalPorMedico.get(m.getId())), null, null, String.format("$%10.2f", total)
      ));
    }

    return l;
  }

}
